﻿using DotNetCore.CAP.Messages;
using Exceptionless;
using Exceptionless.AspNetCore;
using Exceptionless.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Ongoal.Quotation.Log;
using Ongoal.Quotation.Model;
using Polly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using WebApiClientCore;
using WebApiClientCore.Attributes;
using WebApiClientCore.HttpMessageHandlers;

namespace Ongoal.Quotation.Http
{
    /// <summary>
    /// 内部API拦截器
    /// </summary>
    internal class InternalApiFilterAttribute : ApiFilterAttribute
    {
        public IConfiguration _config;
        public InternalApiFilterAttribute(IConfiguration config)
        {
            _config = config;
        }
        public override Task OnRequestAsync(ApiRequestContext context)
        {
            if (context.ActionDescriptor.Attributes.Any(m => m.GetType() == typeof(ExternalApiFilterAttribute)))
            {
                return Task.CompletedTask;
            }
            if (context.ActionDescriptor.FilterAttributes.Any(m => m.GetType() == typeof(ExternalApiFilterAttribute)))
            {
                return Task.CompletedTask;
            }
            var request = context.HttpContext.RequestMessage;
            if (ServiceProviderContext.HttpContextAccessor != null && ServiceProviderContext.HttpContextAccessor.HttpContext != null)
            {
                var currentHeaders = ServiceProviderContext.HttpContextAccessor.HttpContext.Request.Headers;
                string[] nohead = new string[] { "Accept", ":method", "Method", "Content-Type", "Transfer-Encoding", "Access-Control-Allow-Credentials", "Access-Control-Allow-Origin", "Connection", "Server", "Vary", "Content-Length" };
                foreach (var item in currentHeaders)
                {
                    if (nohead.Contains(item.Key))
                    {
                        continue;
                    }

                    request.Headers.Add(item.Key, item.Value.ToString());
                }
                if (!request.Headers.Contains("internalrequest"))
                    request.Headers.Add("internalrequest", ServiceProviderContext.HttpContextAccessor.HttpContext.Request.Path);
                if (!request.Headers.Contains("Authorization"))
                {
                    //没有Token 或者是 调试模式
                    string token = GetLoginToken();
                    if (token == null)
                        throw new Exception("无法获取当前登录信息");
                    request.Headers.Add("Authorization", token);
                }
            }
            else//无上下文,适合定时任务
            {
                string token = GetLoginToken();
                if (token == null)
                    throw new Exception("无法获取当前登录信息");
                request.Headers.Add("Authorization", token);
            }
            //if (headers != null)
            //{
            //    foreach (var item in headers)
            //    {
            //        request.Headers.Add(item.Key, item.Value);
            //    }
            //}
            return Task.CompletedTask;
        }
        public override Task OnResponseAsync(ApiResponseContext context)
        {
            EventBuilder eventBuilder = null;
            if(context.ResultStatus== ResultStatus.HasException)
            {
                //DefaultHttpContext a= new DefaultHttpContext() { };
                //a.Response.ContentType=context.HttpContext.ResponseMessage.
                //Microsoft.AspNetCore.Http.HttpContext a=new Microsoft.AspNetCore.Http.HttpContext()
                eventBuilder = context.Exception.ToExceptionless()
                    .AddTags(DistributedLogTagConstant.ExternaInterface);
            }
            else
            {
                eventBuilder = ExceptionlessClient.Default.CreateLog(null, "接口调用", LogLevel.Trace)
                    .AddTags(DistributedLogTagConstant.ExternaInterface)
                    .AddObject(context.Result, "ReturnData");
            }
            eventBuilder.PluginContextData.Add("WebApiContent", context);
            eventBuilder.Submit();

            return Task.CompletedTask;
        }
        private string GetLoginToken()
        {
            if (ServiceProviderContext.HttpContextAccessor.HttpContext == null)
            {
                //检查是否是开发环境，如果是开发环境，直接返回成功
                if (_config.GetValue<bool>("ASPNETCORE_AUTOTASK") == true)
                {
                    var devCfg = _config.GetCfgValue<DevSetting>("DevSetting");
                    if (devCfg != null)
                    {
                        List<Claim> claims = new List<Claim>();
                        claims.Add(new Claim("loginuser", Des.Encrypt(JsonConvert.SerializeObject(devCfg.User))));
                        var _jwt = ServiceProviderContext.ServiceProvider.GetService(typeof(IAuthentication)) as IAuthentication;
                        if (_jwt != null)
                        {
                            return _jwt.GetToken(claims);
                        }
                    }
                }
            }
            else
            {
                var request = ServiceProviderContext.HttpContextAccessor.HttpContext!.Request;
                if (request.Headers.Keys.Contains("Authorization"))
                {
                    //有登录信息，直接返回Token
                    return request.Headers["Authorization"];
                }
                else
                {
                    var _jwt = ServiceProviderContext.ServiceProvider.GetService(typeof(IAuthentication)) as IAuthentication;
                    var httpContext = ServiceProviderContext.HttpContextAccessor.HttpContext;
                    if (_jwt != null)
                    {
                        return _jwt.GetToken(httpContext!.Request.HttpContext.User.Claims.ToList());
                    }
                }
            }
            return null;

        }
    }
}
